import datetime
import glob
import time

import pandas as pd
from dev.stock_information.stocks_information import get_aStock_zh_a_spot
from dev.entity.stock import Stock
from dev.stock_visual.report_generate import Stock_mpf_Render_Json,Report_Based_Mpf
from dev.stock_visual.email_send import EmailSender
from dev.stock_visual.oss import OSS
from pathlib import Path

import sys
import os
import json
curPath = os.path.abspath(os.path.dirname(__file__))
rootPath = os.path.split(curPath)[0]
sys.path.append(rootPath)

stockCode_Dir = os.path.join(curPath,"resources")

#加载json配置文件
def json_load(filePath):
    # 读取文件数据，如果json中中文出现乱码，参考https://blog.csdn.net/qq_41375318/article/details/128098209
    f = open(filePath, "r", encoding='utf-8-sig', errors='ignore')
    json_data = json.load(f)
    return json_data

#根据配置文件进行方案整合
class SolutionIntegrate:

    def __init__(self,emailSender,oss_obj,codes=[],saveDir="",stocks_config={}):
        '''
        @param codes 要诊股的股票，type=list
        @param saveDir 分析报告生成的文件夹位置，type=str
        @param stocks_config 所有股票使用相同封装的参数，type=dict
        @param emailSender 邮件发送对象； type=EmailSender
        @param oss 图床对象； type=OSS
        '''
        self.codes = codes
        self.saveDir = saveDir
        self.stocks_config = stocks_config
        self.code_name_dict = self.get_stocks_name()

        self.stock_render_jsons = []  #股票信息列表，可以动态渲染到html中
        self.html_report = None  #动态生成html的报告对象
        self.emailSender = emailSender  #邮件发送对象
        self.oss_obj = oss_obj #图床对象

    #获取所有股票名称
    def get_stocks_name(self):
        '''
        @return 股票编码即字典，type=dict, key=code,value=name
        先判断该文件是否为今天的数据，如果不是再更新csv
        '''
        # raise Exception(f"{os.path.join(stockCode_Dir,'*_*.csv')},{glob.glob(os.path.join(stockCode_Dir,'*_*.csv'))}")
        stock_filePath = glob.glob(os.path.join(stockCode_Dir,"*_*.csv"))[0]
        fileName = Path(stock_filePath).name
        tokens = fileName.split("_")
        file_date= tokens[0]

        res_df = None
        #当前的股票代码文件不是最新的,则删除掉原文件再更新写入
        today = datetime.datetime.strptime(datetime.datetime.now().strftime("%Y-%m-%d"),"%Y-%m-%d")  #datetime类型
        if((datetime.datetime.strptime(file_date,"%Y-%m-%d") - today).days < 0):
            res_df = get_aStock_zh_a_spot()
            new_stockPath = os.path.join(stockCode_Dir,datetime.datetime.now().strftime("%Y-%m-%d") + "_" + tokens[1])
            res_df.to_csv(new_stockPath,index=False)
            os.remove(stock_filePath)
        else:
            res_df = pd.read_csv(stock_filePath)

        print(res_df)
        codes = list(res_df['代码'].values)
        names = list(res_df['名称'].values)
        code_name_dict = {}
        for i in range(len(codes)):
            code_name_dict[codes[i]] = names[i]
        return code_name_dict

    #诊股入口函数
    def integrate(self):
        for code in self.codes:
            codeName = self.code_name_dict[code]
            sub_saveDir = os.path.join(self.saveDir, code)
            stock = Stock(code=code, codeName=codeName, saveDir=sub_saveDir)  # 初始化股票Stock对象

            # 分时K线
            stock.set_minute_K_line(period=self.stocks_config["minute_K"]["period"], indices_params=self.stocks_config["minute_K"]["indices_params"])

            # 日K线（默认使用最新的end_date）
            end_date = datetime.datetime.now().strftime("%Y%m%d")
            start_date, end_date = self.stocks_config["daily_K"]["start_date"], end_date
            indices_params = self.stocks_config["daily_K"]["indices_params"]
            indices_dict = self.stocks_config["daily_K"]["indices_useflag_dict"]
            stock.set_daily_K_line(start_date=start_date, end_date=end_date, indices_params=indices_params,
                                   indices_useflag_dict=indices_dict)

            # 周K线（默认使用最新的end_date）
            start_date, end_date = self.stocks_config["week_K"]["start_date"], end_date
            indices_params = self.stocks_config["week_K"]["indices_params"]
            indices_dict = self.stocks_config["week_K"]["indices_useflag_dict"]
            stock.set_week_K_line(start_date=start_date, end_date=end_date, indices_params=indices_params,
                                  indices_useflag_dict=indices_dict)

            #月K线（默认使用最新的end_date）
            start_date, end_date = self.stocks_config["month_K"]["start_date"], end_date
            indices_params = self.stocks_config["month_K"]["indices_params"]
            indices_dict = self.stocks_config["month_K"]["indices_useflag_dict"]
            stock.set_month_K_line(start_date=start_date, end_date=end_date, indices_params=indices_params,
                                   indices_useflag_dict=indices_dict)

            #绘制关于这只股票的分时K线，日K线，周K线和月K线
            stock.plot_K_line()

            picPaths_dict = stock.get_savePaths_dict()
            #上传到OSS中，并返回文件url集合,type=dict
            # pic_urls_dict = oss_upload() #..................
            pic_urls_dict = self.oss_obj.upload_files(picPaths_dict=picPaths_dict)

            minute_kline_path = pic_urls_dict['minute_kline_path'] if "minute_kline_path" in pic_urls_dict.keys() else ""
            daily_kline_path = pic_urls_dict['daily_kline_path'] if "daily_kline_path" in pic_urls_dict.keys() else ""
            week_kline_path = pic_urls_dict['week_kline_path'] if "week_kline_path" in pic_urls_dict.keys() else ""
            month_kline_path = pic_urls_dict['month_kline_path'] if "month_kline_path" in pic_urls_dict.keys() else ""
            stock_render_obj = Stock_mpf_Render_Json()  #初始化动态渲染对象
            stock_render_obj.set_stock_render_json(code=code,
                                                  codeName=codeName,
                                                  minute_kline_path=minute_kline_path,
                                                  daily_kline_path=daily_kline_path,
                                                  week_kline_path=week_kline_path,
                                                  month_kline_path=month_kline_path)
            stock_render_json = stock_render_obj.get_stock_render_json()
            self.stock_render_jsons.append(stock_render_json)

        #初始化报告对象
        self.html_report = Report_Based_Mpf(self.stock_render_jsons)
        timestramp = time.time()
        html_savePath = os.path.join(self.saveDir,"report",f"report_{str(timestramp)}.html")
        self.html_report.generate_html(html_savePath)  #生成报告

        #发送html邮件
        self.emailSender.email_wrapper(filePath=html_savePath, fileType="html")
        self.emailSender.sendEmail()

if __name__ == '__main__':

    saveDir = os.path.join(curPath,"resources")
    res_dict = json_load(os.path.join(saveDir,"stock_config.json"))  # 加载json配置文件

    codes = res_dict['codes']
    stocks_config = res_dict["stocks_config"]

    emailSender_config = res_dict['emailSender']
    emailSender = EmailSender(
        mail_host=emailSender_config["mail_host"],
        mail_user=emailSender_config["mail_user"],
        mail_pass=emailSender_config["mail_pass"],
        sender=emailSender_config["sender"])  # 初始化一个邮件发送对象
    # 初始化一封信
    emailSender.init_email(receivers=emailSender_config["receivers"], content=emailSender_config["content"], subject=emailSender_config["subject"])

    # 阿里云OSS使用流程 参考 https://zhuanlan.zhihu.com/p/567771838
    aliyun_oss_config = res_dict['aliyun_oss']
    ACCESS_KEY_ID = aliyun_oss_config[
        "ACCESS_KEY_ID"]  # RAM账号access_key_id,如果没有用主账号登录工作台创建并授权，关于RAM角色参考 https://ram.console.aliyun.com/roles
    ACCESS_KEY_SECRET = aliyun_oss_config["ACCESS_KEY_SECRET"]  # RAM账号access_key_secret
    ENDPOINT = aliyun_oss_config["ENDPOINT"]  # 可以在bucket中获取地域节点endpoint 参考 https://zhuanlan.zhihu.com/p/567771838
    BUCKET_NAME = aliyun_oss_config["BUCKET_NAME"]
    oss_obj = OSS(access_key_id=ACCESS_KEY_ID, access_key_secret=ACCESS_KEY_SECRET, endpoint=ENDPOINT,
                  bucket_name=BUCKET_NAME)

    integrate = SolutionIntegrate(codes=codes, saveDir=saveDir,stocks_config=stocks_config,emailSender=emailSender,oss_obj=oss_obj) #初始化方案集成对象
    #发送一封股票分析报告
    integrate.integrate()







